package com.hos.utils;

import com.hos.bean.AppInfo;
import com.hos.bean.WriteResult;
import com.hos.json.JSONObject;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSTypedData;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;

public class FileUtils {
    private static String filePath = null;
    private static SimpleDateFormat mFormat;

    /**
     * 保存上传的文件
     */
    public static WriteResult writeToFile(HttpServletRequest request) {
        try {
            String upload_path = getWriteFilePath();
            if (upload_path == null) {
                return new WriteResult(true, "读取配置文件失败");
            }
            List<FileItem> list = createCacheDir(request, upload_path);
            if (list == null || list.size() == 0) {
                return new WriteResult(true, "创建缓存文件夹失败");
            }
            if (list.size() > 1) {
                return new WriteResult(true, "每次只能上传一个文件");
            }
            FileItem uploadFile = list.get(0);
            String prefix = uploadFile.getName().substring(uploadFile.getName().lastIndexOf(".") + 1);
            if (!prefix.equals("p7b")) {
                return new WriteResult(true, "您上传的文件类型不是.p7b");
            }
            // 读取应用信息
            AppInfo appInfo = readAppInfo(uploadFile);
            // 保存的文件路径
            String p7bPath = upload_path + File.separator + "upload" + File.separator;
            // 保存文件逻辑
            createRealFile(uploadFile, new File(p7bPath + appInfo.getP7bFileName()));
            return new WriteResult(false, appInfo.getDevelopmentCertificate());
        } catch (Exception e) {
            return new WriteResult(true, "异常:" + e.getMessage());
        }
    }

    /**
     * 读取p7b文件内的应用信息
     */
    private static AppInfo readAppInfo(FileItem uploadFile) throws Exception {
        CMSSignedData signedData = new CMSSignedData(uploadFile.getInputStream());
        CMSTypedData signedContent = signedData.getSignedContent();
        byte[] bytes = (byte[]) signedContent.getContent();
        String content = new String(bytes, StandardCharsets.UTF_8);
        JSONObject jsonObject = new JSONObject(content);
        String type = jsonObject.getString("type");
        JSONObject bundleInfo = jsonObject.getJSONObject("bundle-info");
        String bundle_name = bundleInfo.getString("bundle-name");
        String developer_id = bundleInfo.getString("developer-id");
        String app_identifier = bundleInfo.getString("app-identifier");
        String certificate;
        if (bundleInfo.has("development-certificate")) {
            certificate = bundleInfo.getString("development-certificate");
        }else {
            certificate = bundleInfo.getString("distribution-certificate");
        }
        // 保存p7b文件的名称拼接
        String sb = app_identifier + "_" + getTime() + "_" + developer_id + "_" + type + "_" + bundle_name + "_" + uploadFile.getName();
        return new AppInfo(sb, certificate);
    }

    /**
     * 创建上传的文件
     */
    private static void createRealFile(FileItem item, File fileName) throws Exception {
        boolean mkdirs = fileName.getParentFile().mkdirs();
        boolean newFile = fileName.createNewFile();
        InputStream is = item.getInputStream();
        int len;
        byte[] bytes = new byte[1024];
        FileOutputStream fos = new FileOutputStream(fileName);
        while ((len = is.read(bytes)) > 0) {
            fos.write(bytes, 0, len);
        }
        is.close();
        fos.close();
    }

    /**
     * 创建缓存文件夹
     */
    private static List<FileItem> createCacheDir(HttpServletRequest request, String path) throws Exception {
        String cachePath = path + File.separator + "cache";
        File cacheFile = new File(cachePath);
        if (!cacheFile.exists()) {
            boolean mkdirs = cacheFile.mkdirs();
        }
        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setRepository(cacheFile);
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        fileUpload.setHeaderEncoding("utf-8");
        return fileUpload.parseRequest(request);
    }

    /**
     * 读取配置文件
     */
    private static String getWriteFilePath() throws Exception {
        if (filePath != null) {
            return filePath;
        }
        InputStream is = FileUtils.class.getClassLoader().getResourceAsStream("/path.properties");
        Properties properties = new Properties();
        properties.load(is);
        filePath = properties.getProperty("path");
        return filePath;
    }


    /**
     * 转化时间戳
     */
    private static String getTime() {
        if (mFormat == null) {
            mFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINESE);
        }
        return mFormat.format(new Date());
    }
}
